package com.magima.core.prompt;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.magima.core.app.BaseApplication;
import com.magima.core.app.IPromptEntry;
import com.magima.core.app.PromptCallback;

public class PromptEntry extends TreeNode<List<PromptCallback>> implements IPromptEntry{
	private String name;
	private int value;
	private BaseApplication app;

	public PromptEntry(PromptCallback data, BaseApplication app) {
		this(data, 0, null, app);
	}
	public PromptEntry(PromptCallback data, String name, BaseApplication app) {
		this(data, 0, name, app);
	}
	public PromptEntry(PromptCallback data, int initialValue, String name, BaseApplication app) {
		super(null);
		this.data = new ArrayList<PromptCallback>();
		if ( data != null)
			this.data.add(data);
		
		value = initialValue;
		this.name = name;
		this.app = app;
	}

    @Override
	public IPromptEntry addListener(PromptCallback callback){
		synchronized(data){
			if ( callback != null && !this.data.contains(callback) )
				this.data.add(callback);
		}
		return this;
	}

    @Override
    public IPromptEntry removeListener(PromptCallback callback){
		synchronized(data){
			this.data.remove(callback);
		}
		return this;
	}

    @Override
	public IPromptEntry findByName(String name){
		if ( this.name != null && this.name.equals(name) )
			return this;
		if ( children == null)
			return null;
		if ( children.get(name) != null )
			return (PromptEntry)children.get(name);
		for (Map.Entry<String,TreeNode<List<PromptCallback>>> entry : children.entrySet() ){
            IPromptEntry ret = ((PromptEntry)entry.getValue()).findByName(name);
			if ( ret != null )
				return (PromptEntry)ret;
		}
		return null;
	}

    @Override
    public void removeChild(IPromptEntry entry){
        super.removeChild((PromptEntry)(entry));
        notifyValueChange();
    }

    @Override
	public void addChild(IPromptEntry data) {
		String id = ((PromptEntry)data).getName();
		super.addChild(((PromptEntry)data), id);
		//if ( ((RedDotEntry)data).getShowingValue() != 0 )
			notifyValueChange();
	}

    @Override
	public void moveTo(IPromptEntry newParentDot){
		if ( parent == newParentDot || newParentDot == this) {
			return;
		}
		synchronized (this){
			getParent().removeChild(this);
			newParentDot.addChild(this);
		}
	}

    @Override
	public void resetChildren(List<IPromptEntry> childList){
		//int beforeAddValue = getShowingValue();
		super.removeAllChildren();
		
		for ( IPromptEntry child : childList ) {
			super.addChild((PromptEntry)child, child.getName());
		}
		
		//int afterAddValue = getShowingValue();
		//if ( beforeAddValue != afterAddValue )
			notifyValueChange();
	}

    @Override
	public int getShowingValue(){
		int total = value;
		if ( children != null ) {
			for (Map.Entry<String,TreeNode<List<PromptCallback>>> entry : children.entrySet()){
				total += ((PromptEntry)entry.getValue()).getShowingValue();
			}
		}
		return total;
	}

    @Override
	public void notifyValueChange(){
		if ( data != null ) {
			app.getPromptManager().gethandler().post(new Runnable(){
				@Override
				public void run() {
					synchronized(data){
						for ( PromptCallback callback : data){
							try {
								callback.onValueChanged(PromptEntry.this, PromptEntry.this.getShowingValue());
							} catch ( Exception e) {
								e.printStackTrace();
							}
						}
					}
				}
			});
		}
		if ( this.parent != null ){
			getParentEntry().notifyValueChange();
		}
	}

    @Override
	public void setValue(int value){
		if ( this.value != value ) {
			this.value = value;
			notifyValueChange();
		}
	}

    @Override
	public int getValue(){
		return value;
	}

    @Override
	public String getName(){
		return name;
	}

    @Override
	public IPromptEntry getParentEntry(){
		return (PromptEntry) parent;
	}
}